using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Configuration.Extensions;

/// <summary>
/// 配置健康检查
/// </summary>
public class ConfigurationHealthCheck : IHealthCheck
{
    private readonly EnhancedConfigurationMappingFactory _configFactory;
    private readonly ILogger<ConfigurationHealthCheck> _logger;

    public ConfigurationHealthCheck(
        EnhancedConfigurationMappingFactory configFactory,
        ILogger<ConfigurationHealthCheck> logger)
    {
        _configFactory = configFactory ?? throw new ArgumentNullException(nameof(configFactory));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
        try
        {
            _logger.LogDebug("Starting configuration health check...");
            
            var healthReport = _configFactory.GetHealthReport();
            
            if (healthReport.IsHealthy)
            {
                var data = new Dictionary<string, object>
                {
                    ["checkedAt"] = healthReport.CheckedAt,
                    ["sectionsCount"] = healthReport.Sections.Count,
                    ["healthySections"] = healthReport.Sections.Count(s => s.IsHealthy)
                };

                if (healthReport.Warnings.Count > 0)
                {
                    data["warnings"] = healthReport.Warnings;
                }

                _logger.LogDebug("Configuration health check passed with {WarningCount} warnings", 
                    healthReport.Warnings.Count);

                return Task.FromResult(
                    healthReport.Warnings.Count > 0 
                        ? HealthCheckResult.Degraded("Configuration has warnings", data: data)
                        : HealthCheckResult.Healthy("All configuration sections are healthy", data));
            }
            else
            {
                var data = new Dictionary<string, object>
                {
                    ["checkedAt"] = healthReport.CheckedAt,
                    ["issues"] = healthReport.Issues,
                    ["failedSections"] = healthReport.Sections.Where(s => !s.IsHealthy).Select(s => s.SectionName).ToArray()
                };

                _logger.LogWarning("Configuration health check failed with {IssueCount} issues: {Issues}",
                    healthReport.Issues.Count, string.Join("; ", healthReport.Issues));

                return Task.FromResult(
                    HealthCheckResult.Unhealthy("Configuration validation failed", 
                        data: data));
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Configuration health check encountered an error");
            
            return Task.FromResult(
                HealthCheckResult.Unhealthy("Configuration health check failed", ex));
        }
    }
}
